home *** CD-ROM | disk | FTP | other *** search
/ DOpus Plus / DOpus Plus.iso / Tutorial / C Guide / Simple_Module2 / IPCWindow / IPCWindow.c < prev    next >
C/C++ Source or Header  |  1998-09-01  |  12KB  |  306 lines

  1. /*******************************************************************
  2.  
  3.    IPCWindow.c
  4.     
  5.     Does open a simple window with some easy gadgets, does create a
  6.     new process, is protected to launch not twice and does show all
  7.     arguments even if they are given with a new command.
  8.                     
  9. *********************************************************************/
  10.  
  11. #define PARENT
  12. #include "/includes/Window.h"
  13.  
  14. typedef struct _PassingData
  15. {
  16.         ULONG a4;                 // to store a4 (module is a4 relative)
  17.         struct Library *library;  // to store a pointer to dopus5.library 
  18.         struct Library *module;   // to store a pointer to this module
  19.         IPCData *ipc;             // to store our NEW handle
  20.              
  21.         struct Screen *screen;
  22. }  PassingData;   
  23.  
  24. /********************************************************************/
  25. // locale prototypes and variables
  26.  
  27. ULONG __asm __saveds New_Proc_Startup( register __a0 IPCData *ipc,
  28.                                        register __a1 PassingData *pd );
  29.                                                                                                         
  30. void __saveds New_Proc( void ); 
  31.  
  32. BOOL OpenDOpusWin( WindowHandle *wh ); // the same old function
  33.  
  34. BOOL HandleWindow( WindowHandle *wh ); // the same old function
  35.  
  36.  
  37. extern IPCData *proc_ipc;
  38. // declared in modinit.c, because must be initialized to NULL on startup 
  39.  
  40. /********************************************************************/
  41. // this is the same function like in DetachWindow.
  42. // it is the first special function we need...
  43.  
  44. void OwnWindow( STRPTR args, struct Screen *screen )
  45. {
  46.     PassingData *pd;
  47.         
  48.    if( (pd = AllocMemH(mempool, sizeof(PassingData))) ) // allocate some memory
  49.      {
  50.           pd->screen = screen;          // store the screen pointer
  51.                 
  52.           if( !proc_ipc ) // only if the process is not already running
  53.             {
  54.                  // now some special stuff, but everything is needed here...
  55.              pd->a4      = getreg( REG_A4 ); 
  56.              pd->module  = (struct Library *) getreg( REG_A6 );
  57.              pd->library = DOpusBase;
  58.                   
  59.              // now we are ready to call IPC_Launch()
  60.              IPC_Launch( 0, 
  61.                          &proc_ipc,         // pointer to pointer to the IPC of the new process, for storing...
  62.                          "ExampleWindow",  // name of the new process
  63.                          (ULONG) New_Proc, // entrypoint of the new process
  64.                          4096,             // stack to use
  65.                          (ULONG) pd,       // data to pass to the new process
  66.                          DOSBase );        // pointer to dos.library
  67.                                  
  68.                  
  69.                                                   
  70.              if( !proc_ipc )              // if detaching failed...
  71.                    {
  72.                         FreeMemH( pd );
  73.                       return;
  74.                     }
  75.                     
  76.                  Delay( 10 ); // give a small time for startup...
  77.                               // not really needed
  78.              }
  79.              
  80.           // now should our process running
  81.           // since we use in the process not the arguments on startup to save
  82.           // some work, we have to pass it now.
  83.           
  84.           IPC_Command( proc_ipc,  // "address" (IPCData) of receiver
  85.                        NULL,      // we use no commands here
  86.                             NULL,      // also no flags
  87.                             args,      // our data to pass to the new process
  88.                             NULL,      // no other data (will be FreeVec'd)
  89.                             REPLY_NO_PORT ); // use normal DOpus IPC_Reply() later
  90.                             
  91.          FreeMemH( pd );
  92.       }
  93.           // ready... :)
  94. }
  95.  
  96. // let's do now the second special function
  97.  
  98. ULONG __asm __saveds New_Proc_Startup( register __a0 IPCData *ipc,
  99.                                        register __a1 PassingData *pd )
  100. {
  101.         // you may use this function also to setup things for your
  102.         // main process, but you should not call any IPC functions here !
  103.         // we do only the minimum required..., but you will get some small
  104.         // warnings from your compiler. Just ignore them now - they does
  105.         // not appear, if we would do here some more things... 
  106.         
  107.         struct Library *DOpusBase; 
  108.  
  109.         // fix A4
  110.         putreg( REG_A4, pd->a4 );
  111.  
  112.         // store IPC pointer
  113.         pd->ipc = ipc;
  114.  
  115.         // get dopus.library - one warning now
  116.         DOpusBase = pd->library;
  117.  
  118.         // now may follow your initialization
  119.         
  120.         // if something fails and you must quit, you should do:
  121.         // return FALSE;
  122.  
  123.         // increase our library counter, so we can not be flushed
  124.         // do not forget to decrease it, if your detached process ends 
  125.         pd->module->lib_OpenCnt++;
  126.         
  127.         return TRUE; // all was successfully
  128.  
  129. void __saveds New_Proc( void )
  130. {
  131.         // this is now just the same like until now our OwnWindow() function
  132.         
  133.         WindowHandle          *wh;
  134.         PassingData           *pd;
  135.           IPCData               *ipc;
  136.           IPCMessage            *ipcmsg;
  137.         struct Library        *DOpusBase;
  138.           struct Library        *module;
  139.         
  140.         // but we must do some additional things 
  141.         
  142.         // get dopus library
  143.         if( !(DOpusBase = (struct Library *) FindName(&((struct ExecBase *)*((ULONG *)4))->LibList, "dopus5.library")) )
  144.                 return;
  145.         
  146.         // do startup 
  147.         ipc = IPC_ProcStartup( (ULONG *) &pd, New_Proc_Startup );
  148.  
  149.         // fix A4 so we can access global data in the module (eg library bases)
  150.         putreg( REG_A4, pd->a4 );
  151.         
  152.           // we must store this pointer too 
  153.           module = pd->module;
  154.           
  155.         // something failed until now ?
  156.         if( !ipc )
  157.           {
  158.                  if( pd )
  159.                {
  160.                         IPC_Free( pd->ipc ); // possible it has a value here 
  161.                   FreeMemH( pd );      // free our memory
  162.                }
  163.                           
  164.              return;
  165.           }
  166.                 
  167.         if( (wh = AllocMemH(mempool, sizeof(WindowHandle))) ) // allocate some memory
  168.           {
  169.              if( OpenDOpusWin(wh) )   // open the window
  170.                {
  171.                         // before we have set on this place the value of our
  172.                         // textgadget, but now we have not the arguments. So
  173.                         // we wait to set the value until the command arrives. 
  174.                         
  175.                         while( TRUE ) 
  176.                     {
  177.                               // I use here Wait(), so it is easier with the changes
  178.                                  
  179.                        wh->signals = Wait( 1 << proc_ipc->command_port->mp_SigBit | // wait for IPC messages
  180.                                                   1 << wh->win->UserPort->mp_SigBit );   // wait for window events
  181.                                                                                                 
  182.                        if( wh->signals & 1 << wh->win->UserPort->mp_SigBit )
  183.                             if( HandleWindow(wh) )
  184.                                  break;           // does end the while loop
  185.                               
  186.                               if( wh->signals & 1 << proc_ipc->command_port->mp_SigBit ) // if we have got an IPC message
  187.                                 {
  188.                                      while( (ipcmsg = (IPCMessage *) GetMsg(proc_ipc->command_port)) )
  189.                                        {
  190.                                             
  191.                                             // we copy now the arguments into the text gadget
  192.                                  // if we have supplied some..., else it will be cleared
  193.                                             // I do not cut here the last signs...
  194.                                  
  195.                                  SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) ipcmsg->data );
  196.                                             
  197.                                             IPC_Reply( ipcmsg ); // do not use ReplyMsg() or something else !
  198.                                         }
  199.                          }                
  200.                     }
  201.                           
  202.                   CloseConfigWindow( wh->win ); 
  203.                 }
  204.                          
  205.               FreeMemH( wh ); // free our memory
  206.           }
  207.              
  208.           // decrease our Library access counter, since we have increased it before
  209.         --module->lib_OpenCnt;   
  210.                             
  211.         // since we are here a detached process, we must do some other cleanup too
  212.         IPC_Free( proc_ipc );
  213.           
  214.           proc_ipc = NULL;    // do not forget this...                                                     
  215.  
  216. /********************************************************************/
  217. // This function does open our window. We could have done this in the
  218. // function OwnWindow() too, but we need this function later again.
  219.  
  220. BOOL OpenDOpusWin( WindowHandle *wh )
  221. {
  222.     NewConfigWindow ncfgwin;     // we need a NewConfigWindow structure too
  223.                                  // of couse you could also allocate it with
  224.                                           // AllocMemH()...
  225.     
  226.     // and have to fill it
  227.     
  228.     ncfgwin.nw_Parent = wh->screen;  // open on this screen
  229.     
  230.     // getting a localized title...
  231.     ncfgwin.nw_Title  = DOpusGetString( locale, MSG_WINDOW_TITLE );
  232.     
  233.     ncfgwin.nw_Dims   = &cfgwin; // a pointer to the ConfigWin structure
  234.     ncfgwin.nw_Locale = locale;  // the module locale pointer (from modinit.c)
  235.     ncfgwin.nw_Port   = NULL;    // we doesn't supply a port
  236.     ncfgwin.nw_Font   = NULL;    // just taking the screen font
  237.     ncfgwin.nw_Flags  = WINDOW_REQ_FILL      | // fill with stripple pattern
  238.                         WINDOW_AUTO_KEYS     | // handle keys automatic
  239.                               WINDOW_SCREEN_PARENT;  // nw_Parent points to a screen
  240.     
  241.     if( (wh->win = OpenConfigWindow(&ncfgwin)) )   // open the window
  242.       {
  243.           if( (wh->olist = AddObjectList(wh->win, odef)) ) // add the gadgets
  244.                   return TRUE;
  245.                     
  246.           CloseConfigWindow( wh->win );    //    in error case do not forget :-)
  247.       }
  248.     
  249.     return FALSE;
  250. }
  251.  
  252.  
  253. /********************************************************************/
  254. // we does only close the window, if the closegadget was pressed
  255. // if you want to close it within a gadget, you must only in the
  256. // right case set "stop" to TRUE
  257.  
  258. BOOL HandleWindow( WindowHandle *wh )
  259. {
  260.      BOOL stop = FALSE;
  261.      ULONG value;
  262.      
  263.      while( !stop && (wh->imsg = GetWindowMsg(wh->win->UserPort)) )
  264.         {
  265.             switch( wh->imsg->Class )  // let's handle the IDCMP
  266.               {
  267.                   case IDCMP_GADGETUP:
  268.                                           switch( GET_ID(wh->imsg) )
  269.                                          {
  270.                                                          case GADGET_ID_CYCLE:  // we copy simply the same text to the text gadget
  271.             
  272.                                                                      value = GetGadgetValue( wh->olist, GADGET_ID_CYCLE ) + MSG_CLICK_ME;
  273.                                                                             SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) DOpusGetString(locale, value) );
  274.                                                                             break;
  275.             
  276.                                               case GADGET_ID_OKAY:   // doing a message
  277.                                                                      
  278.                                                                                         SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) DOpusGetString(locale, MSG_OKAY_DONE) );
  279.                                                                             break;
  280.                                                      
  281.                                               case GADGET_ID_CANCEL: 
  282.                                                                      SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) DOpusGetString(locale, MSG_CANCEL_DONE) );
  283.                                                                             break;
  284.                                           }
  285.                                                                  
  286.                                                   break;
  287.                                      
  288.                   case IDCMP_CLOSEWINDOW:
  289.                                           // we can not simply return here, the IntuiMessage must replied first
  290.                                                   
  291.                                                stop = TRUE;
  292.                                                   break;                                     
  293.               }
  294.                                  
  295.             ReplyWindowMsg( wh->imsg );  
  296.                               
  297.             // remember: You should not use any other routines
  298.             // to get/reply the messages of this window than
  299.             // GetWindowMsg() and ReplyWindowMsg() !!
  300.        }
  301.                                
  302.     return stop;
  303. }
  304.